package br.ufrn.cep.eEtica.integracao.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@Entity
public class Projeto {

	@Id
	private String protocolo;
	private String nome;
	private Date dataEntrega;
	private Date reuniaoInicial;
	private int folhaDeRosto;
	private int caae;

	@Enumerated(EnumType.STRING)
	private Grupo grupo;

	@ManyToOne
	@JoinColumn(name = "areaconhecimento_fk")
	private AreaConhecimento areaConhecimento;

	@ManyToOne
	@JoinColumn(name = "subareaconhecimento_fk")
	private AreaConhecimento subAreaConhecimento;

	@ManyToOne
	@JoinColumn(name = "instituicaoproponente_fk")
	private Instituicao instituicaoProponente;

	@OneToMany
	@JoinTable(name = "projeto_instituicao", joinColumns = { @JoinColumn(name = "projeto_id") }, inverseJoinColumns = { @JoinColumn(name = "instituicao_id") })
	private List<Instituicao> instituicoesCoParticipantes = new ArrayList<Instituicao>();

	@Enumerated(EnumType.STRING)
	private NivelAbrangencia nivelAbrangencia;

	@Temporal(TemporalType.DATE)
	private Date arrolamentoInicio;

	@Temporal(TemporalType.DATE)
	private Date arrolamentoFinal;

	@Temporal(TemporalType.DATE)
	private Date cronogramaInicio;

	@Temporal(TemporalType.DATE)
	private Date cronogramaFinal;

	@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST,
			CascadeType.REFRESH })
	@JoinColumn(name = "pesquisadorresponsavel_fk")
	private Pesquisador pesquisadorResponsavel;

	@OneToMany
	@JoinTable(name = "projeto_pesquisadores", joinColumns = { @JoinColumn(name = "projeto_id") }, inverseJoinColumns = { @JoinColumn(name = "pesquisador_id") })
	private List<Pesquisador> pesquisadoresParticipantes = new ArrayList<Pesquisador>();

	@OneToMany(cascade = CascadeType.ALL)
	@JoinTable(name = "projeto_documento", joinColumns = { @JoinColumn(name = "projeto_id") }, inverseJoinColumns = { @JoinColumn(name = "documento_id") })
	private List<Documento> documentos = new ArrayList<Documento>();

	@ManyToOne
	@JoinColumn(name = "revisor_fk")
	private Revisor revisor;

	@OneToMany(cascade = CascadeType.ALL)
	@JoinTable(name = "projeto_status", joinColumns = { @JoinColumn(name = "projeto_id") }, inverseJoinColumns = { @JoinColumn(name = "status_id") })
	private List<StatusProjeto> statusDoProjeto = new ArrayList<StatusProjeto>();

	public Projeto() {
		
	}

	@XmlElement
	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	@XmlElement
	public Date getDataEntrega() {
		return dataEntrega;
	}

	public void setDataEntrega(Date dataEntrega) {
		this.dataEntrega = dataEntrega;
	}

	@XmlElement
	public Date getReuniaoInicial() {
		return reuniaoInicial;
	}

	public void setReuniaoInicial(Date reuniaoInicial) {
		this.reuniaoInicial = reuniaoInicial;
	}

	@XmlElement
	public int getFolhaDeRosto() {
		return folhaDeRosto;
	}

	public void setFolhaDeRosto(int folhaDeRosto) {
		this.folhaDeRosto = folhaDeRosto;
	}

	@XmlElement
	public int getCaae() {
		return caae;
	}

	public void setCaae(int caae) {
		this.caae = caae;
	}

	@XmlElement
	public Grupo getGrupo() {
		return grupo;
	}

	public void setGrupo(Grupo grupo) {
		this.grupo = grupo;
	}

	@XmlElement
	public AreaConhecimento getAreaConhecimento() {
		return areaConhecimento;
	}

	public void setAreaConhecimento(AreaConhecimento areaConhecimento) {
		this.areaConhecimento = areaConhecimento;
	}

	@XmlElement
	public AreaConhecimento getSubAreaConhecimento() {
		return subAreaConhecimento;
	}

	public void setSubAreaConhecimento(AreaConhecimento subAreaConhecimento) {
		this.subAreaConhecimento = subAreaConhecimento;
	}

	@XmlElement
	public Instituicao getInstituicaoProponente() {
		return instituicaoProponente;
	}

	public void setInstituicaoProponente(Instituicao instituicaoProponente) {
		this.instituicaoProponente = instituicaoProponente;
	}

	@XmlElement
	public List<Instituicao> getInstituicoesCoParticipantes() {
		return instituicoesCoParticipantes;
	}

	public void setInstituicoesCoParticipantes(
			List<Instituicao> instituicoesCoParticipantes) {
		this.instituicoesCoParticipantes = instituicoesCoParticipantes;
	}

	public void addInstituicaoCoParticipante(Instituicao instituicao) {
		this.instituicoesCoParticipantes.add(instituicao);
	}

	@XmlElement
	public NivelAbrangencia getNivelAbrangencia() {
		return nivelAbrangencia;
	}

	public void setNivelAbrangencia(NivelAbrangencia nivelAbrangencia) {
		this.nivelAbrangencia = nivelAbrangencia;
	}

	@XmlElement
	public Date getArrolamentoInicio() {
		return arrolamentoInicio;
	}

	public void setArrolamentoInicio(Date arrolamentoInicio) {
		this.arrolamentoInicio = arrolamentoInicio;
	}

	@XmlElement
	public Date getArrolamentoFinal() {
		return arrolamentoFinal;
	}

	public void setArrolamentoFinal(Date arrolamentoFinal) {
		this.arrolamentoFinal = arrolamentoFinal;
	}

	@XmlElement
	public Date getCronogramaInicio() {
		return cronogramaInicio;
	}

	public void setCronogramaInicio(Date cronogramaInicio) {
		this.cronogramaInicio = cronogramaInicio;
	}

	@XmlElement
	public Date getCronogramaFinal() {
		return cronogramaFinal;
	}

	public void setCronogramaFinal(Date cronogramaFinal) {
		this.cronogramaFinal = cronogramaFinal;
	}

	@XmlElement
	public Pesquisador getPesquisadorResponsavel() {
		return pesquisadorResponsavel;
	}

	public void setPesquisadorResponsavel(Pesquisador pesquisadorResponsavel) {
		this.pesquisadorResponsavel = pesquisadorResponsavel;
	}

	@XmlElement
	public List<Pesquisador> getPesquisadoresParticipantes() {
		return pesquisadoresParticipantes;
	}

	public void setPesquisadoresParticipantes(
			List<Pesquisador> pesquisadoresParticipantes) {
		this.pesquisadoresParticipantes = pesquisadoresParticipantes;
	}

	public void addPesquisadorParticipante(Pesquisador pesquisador) {
		this.pesquisadoresParticipantes.add(pesquisador);
	}

	@XmlElement
	public List<Documento> getDocumentos() {
		return documentos;
	}

	public void setDocumentos(List<Documento> documentos) {
		this.documentos = documentos;
	}

	public void addDocumento(Documento documento) {
		this.documentos.add(documento);
	}

	@XmlElement
	public String getProtocolo() {
		return protocolo;
	}

	@XmlElement
	public Revisor getRevisor() {
		return revisor;
	}

	public void setRevisor(Revisor revisor) {
		this.revisor = revisor;
	}

	public void setStatusDoProjeto(List<StatusProjeto> statusDoProjeto) {
		this.statusDoProjeto = statusDoProjeto;
	}

	@XmlElement
	public List<StatusProjeto> getStatusDoProjeto() {
		return statusDoProjeto;
	}

	public void addStatus(StatusProjeto statusProjeto) {
		this.statusDoProjeto.add(statusProjeto);
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime
				* result
				+ ((areaConhecimento == null) ? 0 : areaConhecimento.hashCode());
		result = prime
				* result
				+ ((arrolamentoFinal == null) ? 0 : arrolamentoFinal.hashCode());
		result = prime
				* result
				+ ((arrolamentoInicio == null) ? 0 : arrolamentoInicio
						.hashCode());
		result = prime * result + caae;
		result = prime * result
				+ ((cronogramaFinal == null) ? 0 : cronogramaFinal.hashCode());
		result = prime
				* result
				+ ((cronogramaInicio == null) ? 0 : cronogramaInicio.hashCode());
		result = prime * result
				+ ((dataEntrega == null) ? 0 : dataEntrega.hashCode());
		result = prime * result + folhaDeRosto;
		result = prime * result + ((grupo == null) ? 0 : grupo.hashCode());
		result = prime
				* result
				+ ((instituicaoProponente == null) ? 0 : instituicaoProponente
						.hashCode());
		result = prime
				* result
				+ ((nivelAbrangencia == null) ? 0 : nivelAbrangencia.hashCode());
		result = prime * result + ((nome == null) ? 0 : nome.hashCode());
		result = prime
				* result
				+ ((pesquisadorResponsavel == null) ? 0
						: pesquisadorResponsavel.hashCode());
		result = prime * result
				+ ((protocolo == null) ? 0 : protocolo.hashCode());
		result = prime * result
				+ ((reuniaoInicial == null) ? 0 : reuniaoInicial.hashCode());
		result = prime
				* result
				+ ((subAreaConhecimento == null) ? 0 : subAreaConhecimento
						.hashCode());
		return result;
	}

	public void setProtocolo(String protocolo) {
		this.protocolo = protocolo;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Projeto other = (Projeto) obj;
		if (areaConhecimento == null) {
			if (other.areaConhecimento != null)
				return false;
		} else if (!areaConhecimento.equals(other.areaConhecimento))
			return false;
		if (arrolamentoFinal == null) {
			if (other.arrolamentoFinal != null)
				return false;
		} else if (!arrolamentoFinal.equals(other.arrolamentoFinal))
			return false;
		if (arrolamentoInicio == null) {
			if (other.arrolamentoInicio != null)
				return false;
		} else if (!arrolamentoInicio.equals(other.arrolamentoInicio))
			return false;
		if (caae != other.caae)
			return false;
		if (cronogramaFinal == null) {
			if (other.cronogramaFinal != null)
				return false;
		} else if (!cronogramaFinal.equals(other.cronogramaFinal))
			return false;
		if (cronogramaInicio == null) {
			if (other.cronogramaInicio != null)
				return false;
		} else if (!cronogramaInicio.equals(other.cronogramaInicio))
			return false;
		if (dataEntrega == null) {
			if (other.dataEntrega != null)
				return false;
		} else if (!dataEntrega.equals(other.dataEntrega))
			return false;
		if (folhaDeRosto != other.folhaDeRosto)
			return false;
		if (grupo != other.grupo)
			return false;
		if (instituicaoProponente == null) {
			if (other.instituicaoProponente != null)
				return false;
		} else if (!instituicaoProponente.equals(other.instituicaoProponente))
			return false;
		if (nivelAbrangencia != other.nivelAbrangencia)
			return false;
		if (nome == null) {
			if (other.nome != null)
				return false;
		} else if (!nome.equals(other.nome))
			return false;
		if (pesquisadorResponsavel == null) {
			if (other.pesquisadorResponsavel != null)
				return false;
		} else if (!pesquisadorResponsavel.equals(other.pesquisadorResponsavel))
			return false;
		if (protocolo == null) {
			if (other.protocolo != null)
				return false;
		} else if (!protocolo.equals(other.protocolo))
			return false;
		if (reuniaoInicial == null) {
			if (other.reuniaoInicial != null)
				return false;
		} else if (!reuniaoInicial.equals(other.reuniaoInicial))
			return false;
		if (subAreaConhecimento == null) {
			if (other.subAreaConhecimento != null)
				return false;
		} else if (!subAreaConhecimento.equals(other.subAreaConhecimento))
			return false;
		return true;
	}

}
